/**
 *
 */
package com.engine.salary.util.db;

import org.apache.ibatis.session.SqlSession;
import weaver.conn.mybatis.MyBatisFactory;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * mapper代理工厂
 * <p>Copyright: Copyright (c) 2022</p>
 * <p>Company: 泛微软件</p>
 *
 * @author qiantao
 * @version 1.0
 **/
public class MapperProxyFactory implements InvocationHandler {
    private Class clazz;
    private boolean enableTransactions = false;
    private SqlSession session;

    public MapperProxyFactory(Class clazz) {
        this.clazz = clazz;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Exception {
        this.session = MyBatisFactory.sqlSessionFactory.openSession();
        try {
            Object target = session.getMapper(clazz);
            return method.invoke(target, args);
        } finally {
            if (!enableTransactions) {
                session.commit();
                session.close();
            }
        }
    }

    public Object getProxy() {
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        Class<?>[] interfaces = new Class<?>[1];
        interfaces[0] = this.clazz;
        return Proxy.newProxyInstance(loader, interfaces, this);
    }

    public Object getProxy(boolean enableTransactions) {
        this.enableTransactions = enableTransactions;
        return this.getProxy();
    }

    public void commit() {
        if (this.session != null) {
            this.session.commit();
            this.session.close();
        }
    }

    public void rollback() {
        if (this.session != null) {
            this.session.rollback();
            this.session.close();
        }
    }

    public static <T> T getProxy(Class<T> clazz) {
        MapperProxyFactory handle = new MapperProxyFactory(clazz);
        return (T) handle.getProxy();
    }

    public static <T> T getProxy(Class<T> clazz, boolean enableTransactions) {
        MapperProxyFactory handle = new MapperProxyFactory(clazz);
        return (T) handle.getProxy(enableTransactions);
    }
}
